package com.taijihuabao.modules.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.taijihuabao.common.exception.ServiceException;
import com.taijihuabao.common.jsonresult.ApplicationResponseCode;
import com.taijihuabao.modules.entity.MenuEntity;
import com.taijihuabao.modules.entity.MenuRoleEntity;
import com.taijihuabao.modules.entity.RoleEntity;
import com.taijihuabao.modules.entity.RolePermissionEntity;
import com.taijihuabao.modules.mapper.*;
import com.taijihuabao.modules.model.basedto.IdDTO;
import com.taijihuabao.modules.model.permission.vo.PermissionInfoVO;
import com.taijihuabao.modules.model.role.dto.RoleCrFromDTO;
import com.taijihuabao.modules.model.role.dto.RoleListFromDTO;
import com.taijihuabao.modules.model.role.dto.RoleUpFromDTO;
import com.taijihuabao.modules.model.role.vo.RoleInfoVO;
import com.taijihuabao.modules.model.role.vo.RoleMenuInfoVO;
import com.taijihuabao.modules.service.MenuService;
import com.taijihuabao.modules.service.RoleService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;

/**
 * 角色管理
 *
 * @author chagnhui.tu
 */
@Service
public class RoleServiceImpl implements RoleService {

    @Resource
    private RoleMapper roleMapper;
    @Resource
    private RolePermissionMapper rolePermissionMapper;
    @Resource
    private PermissionMapper permissionMapper;
    @Resource
    private MenuRoleMapper menuRoleMapper;
    @Resource
    private MenuMapper menuMapper;
    @Resource
    private MenuService menuService;

    @Override
    public PageInfo<RoleEntity> selectAllRole(RoleListFromDTO listDTO) throws ServiceException {
        PageHelper.startPage(listDTO.getPage(), listDTO.getSize());
        RoleEntity roleEntity = new RoleEntity();
        roleEntity.setCode(listDTO.getCode());
        roleEntity.setName(listDTO.getName());
        List<RoleEntity> roleEntities = roleMapper.selectAllRole(roleEntity);
        return new PageInfo<>(roleEntities);
    }

    @Override
    public List<RoleEntity> selectRoles() throws ServiceException {
        return roleMapper.selectRoles();
    }

    @Override
    public RoleInfoVO selectRoleById(IdDTO idDTO) throws ServiceException {
        RoleInfoVO roleInfoVO = roleMapper.selectRoleById(idDTO.getId());
        if (roleInfoVO == null) {
            throw new ServiceException(ApplicationResponseCode.ROlE_NOT_EXIST);
        } else {
            return roleInfoVO;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insertRole(RoleCrFromDTO crFromDTO) throws ServiceException {
        RoleEntity roleEntity = new RoleEntity();
        roleEntity.setCode(crFromDTO.getCode());
        roleEntity.setName(crFromDTO.getName());
        roleMapper.insertRole(roleEntity);
        //给角色添加权限
        if (!CollectionUtils.isEmpty(crFromDTO.getPermissions())) {
            for (Long pid : crFromDTO.getPermissions()) {
                //判断pid是否存在
                PermissionInfoVO permissionInfoVO = permissionMapper.selectById(pid);
                if (permissionInfoVO == null) {
                    throw new ServiceException(ApplicationResponseCode.PERMISSION_NOT_ID);
                }
                rolePermissionMapper.insert(new RolePermissionEntity(roleEntity.getId(), pid));
            }
        }
        //给角色添加菜单
        if (!CollectionUtils.isEmpty(crFromDTO.getMenus())) {
            for (Long mid : crFromDTO.getMenus()) {
                //判断mid是否存在
                MenuEntity menuEntity = menuMapper.selectOneById(mid);
                if (menuEntity == null) {
                    throw new ServiceException(ApplicationResponseCode.MENU_NOT_ID);
                }
                menuRoleMapper.insert(new MenuRoleEntity(mid, roleEntity.getId()));
                //拿到当前菜单的所有父级菜单
                List<MenuEntity> parentMenus = menuService.selectParent(mid);
                //给角色添加父级菜单
                for (MenuEntity parentMenu : parentMenus) {
                    //通过角色id拿到当前角色拥有的菜单
                    RoleMenuInfoVO roleMenuInfoVO = roleMapper.selectMenuByRoleId(roleEntity.getId());
                    //判断父级菜单是否重复
                    if (!roleMenuInfoVO.getMenuIds().contains(parentMenu.getId())) {
                        menuRoleMapper.insert(new MenuRoleEntity(parentMenu.getId(), roleEntity.getId()));
                    }
                }
            }
        }
    }

    @Override
    public void updateRole(RoleUpFromDTO upFromDTO) throws ServiceException {
        RoleEntity roleEntity = new RoleEntity();
        roleEntity.setId(upFromDTO.getId());
        roleEntity.setCode(upFromDTO.getCode());
        roleEntity.setName(upFromDTO.getName());
        roleMapper.updateRole(roleEntity);
        //清空角色权限
        if (!CollectionUtils.isEmpty(roleMapper.selectRoleById(roleEntity.getId()).getPermissions())) {
            RolePermissionEntity rolePermissionEntity = new RolePermissionEntity();
            rolePermissionEntity.setRid(roleEntity.getId());
            rolePermissionMapper.delPidByRid(rolePermissionEntity);
        }
        if (!CollectionUtils.isEmpty(upFromDTO.getPermissions())) {
            for (Long pid : upFromDTO.getPermissions()) {
                //判断pid是否存在
                PermissionInfoVO permissionInfoVO = permissionMapper.selectById(pid);
                if (permissionInfoVO == null) {
                    throw new ServiceException(ApplicationResponseCode.PERMISSION_NOT_ID);
                }
                rolePermissionMapper.insert(new RolePermissionEntity(roleEntity.getId(), pid));
            }
        }
        //清空角色菜单
        if (!CollectionUtils.isEmpty(roleMapper.selectRoleById(roleEntity.getId()).getMenus())) {
            MenuRoleEntity menuRoleEntity = new MenuRoleEntity();
            menuRoleEntity.setRid(roleEntity.getId());
            menuRoleMapper.delMidByRid(menuRoleEntity);
        }
        //给角色添加菜单
        if (!CollectionUtils.isEmpty(upFromDTO.getMenus())) {
            for (Long mid : upFromDTO.getMenus()) {
                //判断mid是否存在
                MenuEntity menuEntity = menuMapper.selectOneById(mid);
                if (menuEntity == null) {
                    throw new ServiceException(ApplicationResponseCode.MENU_NOT_ID);
                }
                menuRoleMapper.insert(new MenuRoleEntity(mid, roleEntity.getId()));
                //拿到当前菜单的所有父级菜单
                List<MenuEntity> parentMenus = menuService.selectParent(mid);
                //给角色添加父级菜单
                for (MenuEntity parentMenu : parentMenus) {
                    //通过角色id拿到当前角色拥有的菜单
                    RoleMenuInfoVO roleMenuInfoVO = roleMapper.selectMenuByRoleId(roleEntity.getId());
                    if(!Objects.isNull(roleMenuInfoVO)){
                        //判断父级菜单是否重复
                        if (!roleMenuInfoVO.getMenuIds().contains(parentMenu.getId())) {
                            menuRoleMapper.insert(new MenuRoleEntity(parentMenu.getId(), roleEntity.getId()));
                        }
                    }
                }
            }
        }
    }

    @Override
    public void deleteRole(IdDTO dto) throws ServiceException {
        RoleEntity roleEntity = new RoleEntity();
        roleEntity.setId(dto.getId());
        if (roleMapper.selectRoleById(dto.getId()) == null) {
            throw new ServiceException(ApplicationResponseCode.ID_NOTNULL);
        }
        //判断角色已经删除成功
        if (roleMapper.findIdMark(dto.getId()) != 1) {
            throw new ServiceException(ApplicationResponseCode.ROLE_DELETE);
        }
        roleMapper.deleteRole(roleEntity);
    }

}
